home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / chunky.lha / lib_chunky / lib-src / text.c < prev    next >
C/C++ Source or Header  |  1998-02-27  |  12KB  |  451 lines

  1. #define __CONSTLIBBASEDECL__  const
  2. #include  <proto/graphics.h>
  3. #include  <proto/exec.h>
  4. #include  <dos/dos.h>
  5. #include  "chunky.h"
  6.  
  7. ///"some static prototypes"
  8. static void text_softstyle( struct ChunkyPort *, char *, int );
  9. static void text_chk( struct ChunkyPort *, char *, int );
  10. static void text_w3d( struct ChunkyPort *, char *, int );
  11. static void text_3d ( struct ChunkyPort *, char *, int );
  12. static void text_ol ( struct ChunkyPort *, char *, int );
  13. static void text_emb( struct ChunkyPort *, char *, int );
  14. static void text_bld( struct ChunkyPort *, char *, int );
  15. ///
  16. ///"static inline void text_chk( struct ChunkyPort *, char *, int )"
  17. static inline char get_pen( char *cb, long bpr, long x, long y )
  18. {
  19.     return( *((UBYTE *)((ULONG )cb ) + ( ( bpr * y ) + x ) ) );
  20. }
  21.  
  22. static void text_chk( struct ChunkyPort *cp, char *text, int length )
  23. {
  24.     // Better Text(rp, txt, txtlen) - replacement
  25.     // Init all those static variables
  26.  
  27.     struct TextFont *tf = cp->cp_Font;
  28.     char  dpen = cp->cp_APen;
  29.     int   sx, sy, dx, dy, x, y;
  30.     UBYTE *src = cp->cp_TxtChunky;
  31.     WORD  *cloc = tf->tf_CharLoc;
  32.     UWORD *cspa = tf->tf_CharSpace;
  33.     UWORD *ckern= tf->tf_CharKern;
  34.     int   cwidth, cx, spa, kern;
  35.     int   bpr  = tf->tf_Modulo * 8;
  36.     char  c, p;
  37.  
  38.     if( tf == NULL )          return;
  39.     if( strlen( text ) == 0 ) return;
  40.  
  41.     while( length-- )
  42.     {
  43.         c = *text++;
  44.         // Is the character in the CharLocation ?
  45.         // If not, set it to this 'unknown' amiga character
  46.         if( ( c < tf->tf_LoChar || c > tf->tf_HiChar ) )
  47.             c = tf->tf_HiChar + 1;
  48.  
  49.         // Get real character offset
  50.         // Ie.: if loChar == 'A' then it's the first Character
  51.         // in each offset-table
  52.         c -= tf->tf_LoChar;
  53.         cx     = cloc[ c*2 ];
  54.         cwidth = cloc[ c*2+1];
  55.  
  56.         // NOTE: CharSpace[] and CharKern[] do not exist on some fixed-width-fonts
  57.         spa    = cspa ? cspa[c] : tf->tf_XSize;
  58.         kern   = ckern ? ckern[c] : 0;
  59.  
  60.         // Now we have the following vars set:
  61.         // cx     = #byte-offset of first character-pixel
  62.         // cwidth = real width of character
  63.         // spa    = spacing ( rect of printed character )
  64.         // kern   = kerning ( start of printed char. into those spacing )
  65.  
  66.         sx = cp->cp_cx + kern;
  67.         cp->cp_cx += spa;
  68.  
  69.         sy = cp->cp_cy - cp->cp_TxBaseline;
  70.  
  71.         // Test the various font behavior
  72.         if( cp->cp_Flags == JAM1 ){
  73.  
  74.             for( y = 0; y < tf->tf_YSize; y++ )
  75.             {
  76.                 dx = sx;
  77.                 for( x = cx; x < cx + cwidth; x++ )
  78.                 {
  79.                     p = get_pen( src, bpr, x, y );
  80.                     // only set dest if p != 0
  81.                     if( p ) SET_BYTE( cp, dpen, dx, sy+y );
  82.                     dx++;
  83.                 }
  84.             }
  85.         }
  86.         else if( cp->cp_Flags == JAM2 ){
  87.             for( y = 0; y < tf->tf_YSize; y++ )
  88.             {
  89.                 dx = sx;
  90.                 for( x = cx; x < cx + cwidth; x++ )
  91.                 {
  92.                     p = get_pen( src, bpr, x, y );
  93.                     // if 0x00 -> bpen
  94.                     // if 0x01 -> apen
  95.                     SET_BYTE( cp, p?dpen:cp->cp_BPen, dx++, sy+y );
  96.                 }
  97.             }
  98.         }
  99.         else if( cp->cp_Flags == INVERSVID ){
  100.             for( y = 0; y < tf->tf_YSize; y++ )
  101.             {
  102.                 dx = sx;
  103.                 for( x = cx; x < cx + cwidth; x++ )
  104.                 {
  105.                     p = get_pen( src, bpr, x, y );
  106.                     // if 0x00 -> apen
  107.                     // if 0x01 -> bpen
  108.                     SET_BYTE( cp, p?cp->cp_BPen:dpen, dx++, sy+y );
  109.                 }
  110.             }
  111.         }
  112.     }
  113. }
  114. ///
  115. ///"static inline text_bld( struct ChunkyPort *, char *, int )"
  116. static void text_bld( struct ChunkyPort *cp, char *t, int l)
  117. {
  118.     // draw text bold - twice w/ shifted and or'ed
  119.     int o_f = cp->cp_Flags;
  120.     int x = cp->cp_cx, y = cp->cp_cy;
  121.  
  122.     // needed!
  123.     cp->cp_Flags = JAM1;
  124.     text_chk( cp, t, l );
  125.     MoveChk( cp, x+1, y );
  126.     text_chk( cp, t, l );
  127.     cp->cp_Flags = o_f;
  128. }
  129. ///
  130. ///"text_w3d"
  131. static void text_w3d( struct ChunkyPort *cp, char *t, int l )
  132. {
  133.     // Use bpen as shadow and apen as textpen
  134.     int  x = cp->cp_cx;
  135.     int  y = cp->cp_cy;
  136.     char bpen = cp->cp_BPen;
  137.     char apen = cp->cp_APen;
  138.  
  139.     SetAPenChk( cp, bpen );
  140.  
  141.     // Draw dark shadow of 3d
  142.     text_bld( cp, t, l );
  143.     MoveChk( cp, x-2, y-2 );
  144.  
  145.     // draw light pen of 3d
  146.     SetAPenChk( cp, apen );
  147.     text_chk( cp, t, l );
  148. }
  149. ///
  150. ///"text_3d"
  151. static void text_3d ( struct ChunkyPort *cp, char *t, int l )
  152. {
  153.     // Use bpen as shadow and apen as textpen
  154.     int  x = cp->cp_cx;
  155.     int  y = cp->cp_cy;
  156.     char bpen = cp->cp_BPen;
  157.     char apen = cp->cp_APen;
  158.  
  159.     SetAPenChk( cp, bpen );
  160.  
  161.     if( cp->cp_TxStyle & FSF_BOLD ){
  162.         // Draw dark shadow of 3d
  163.         text_bld( cp, t, l );
  164.         MoveChk( cp, x-2, y-2 );
  165.  
  166.         // draw light pen of 3d
  167.         SetAPenChk( cp, apen );
  168.         text_bld( cp, t, l );
  169.  
  170.     } else {
  171.         // Draw dark shadow of 3d
  172.         text_chk( cp, t, l );
  173.         MoveChk( cp, x-1, y-1 );
  174.  
  175.         // draw light pen of 3d
  176.         SetAPenChk( cp, apen );
  177.         text_chk( cp, t, l );
  178.     }
  179. }
  180. ///
  181. ///"text_ol"
  182. static void text_ol ( struct ChunkyPort *cp, char *t, int l)
  183. {
  184.     UWORD xpos, ypos;
  185.     int   x = cp->cp_cx;
  186.     int   y = cp->cp_cy;
  187.     char  open = cp->cp_OPen;
  188.     char  apen = cp->cp_APen;
  189.     int   o_f = cp->cp_Flags;
  190.  
  191.     cp->cp_Flags = JAM1;
  192.  
  193.     if( cp->cp_TxStyle & FSF_BOLD ){
  194.         SetAPenChk( cp, open );
  195.         for( ypos = y; ypos < y+3; ypos++ ){
  196.             for( xpos = x; xpos < x+3; xpos++){
  197.                 MoveChk( cp, xpos, ypos );
  198.                 text_bld( cp, t, l );
  199.             }
  200.         }
  201.         SetAPenChk( cp, apen );
  202.         MoveChk( cp, x+1, y+1 );
  203.         text_bld( cp, t, l );
  204.     }
  205.     else{
  206.         SetAPenChk( cp, open );
  207.         for( ypos = y; ypos < y+3; ypos++ ){
  208.             for( xpos = x; xpos < x+3; xpos++){
  209.                 MoveChk( cp, xpos, ypos );
  210.                 text_chk( cp, t, l );
  211.             }
  212.         }
  213.         SetAPenChk( cp, apen );
  214.         MoveChk( cp, x+1, y+1 );
  215.         text_chk( cp, t, l );
  216.     }
  217.     cp->cp_Flags = o_f;
  218. }
  219. ///
  220. ///"text_emb"
  221. static void text_emb( struct ChunkyPort *cp, char *t, int l )
  222. {
  223.     // use: - apen as textpen 0/0
  224.     //      - bpen as hshadowpen -1/-1
  225.     //      - open as shinepen +1/+1
  226.     int   x = cp->cp_cx;
  227.     int   y = cp->cp_cy;
  228.     char  open = cp->cp_OPen;
  229.     char  apen = cp->cp_APen;
  230.     char  bpen = cp->cp_BPen;
  231.     int   o_f = cp->cp_Flags;
  232.  
  233.     cp->cp_Flags = JAM1;
  234.  
  235.     if( cp->cp_TxStyle & FSF_BOLD ){
  236.         SetAPenChk( cp, bpen );
  237.         MoveChk( cp, x-1, y-1 );
  238.         text_bld( cp, t, l );
  239.  
  240.         SetAPenChk( cp, open );
  241.         MoveChk( cp, x+1, y+1 );
  242.         text_bld( cp, t, l );
  243.  
  244.         SetAPenChk( cp, apen );
  245.         MoveChk( cp, x, y );
  246.         text_bld( cp, t, l );
  247.     }
  248.     else{
  249.         SetAPenChk( cp, bpen );
  250.         MoveChk( cp, x-1, y-1 );
  251.         text_chk( cp, t, l );
  252.  
  253.         SetAPenChk( cp, open );
  254.         MoveChk( cp, x+1, y+1 );
  255.         text_chk( cp, t, l );
  256.  
  257.         SetAPenChk( cp, apen );
  258.         MoveChk( cp, x, y );
  259.         text_chk( cp, t, l );
  260.     }
  261.     cp->cp_Flags = o_f;
  262. }
  263. ///
  264. ///"static inline void text_softstyle( struct ChunkyPort *, char *, int )"
  265. static inline void text_softstyle( struct ChunkyPort *cp, char *text, int len )
  266. {
  267.     // draw the text with the softstyle set
  268.     // possible combinations of the softstyle:
  269.     //    FSF_BOLD|FSF_3D
  270.     //    FSF_BOLD|FSF_OUTLINE
  271.     //    FSF_BOLD|FSF_EMBOSSED
  272.  
  273.     // First test the normal possibilities
  274.     if( cp->cp_TxStyle == FS_NORMAL ){
  275.         text_chk( cp, text, len );
  276.     } else if( cp->cp_TxStyle == FSF_BOLD ){
  277.         text_bld( cp, text, len );
  278.  
  279.     // Test the possible combinations
  280.     } else if( cp->cp_TxStyle & FSF_3D ){
  281.         text_3d(cp, text, len );
  282.     } else if( cp->cp_TxStyle & FSF_WIDE3D ){
  283.         text_w3d( cp, text, len );
  284.     } else if( cp->cp_TxStyle & FSF_OUTLINE ){
  285.         text_ol ( cp, text, len );
  286.     } else if( cp->cp_TxStyle & FSF_EMBOSSED ){
  287.         text_emb( cp, text, len );
  288.     } else {
  289.         text_chk( cp, text, len );
  290.     }
  291. }
  292. ///
  293. ///"void SetFontChk( struct ChunkyPort *, struct TextFont *)"
  294. void SetFontChk( struct ChunkyPort  *cp, struct TextFont *tf )
  295. {
  296.     // SetFont(rp, font ) - replacement
  297.  
  298.     // Same font? -> return
  299.     if( cp->cp_Font == tf ) return;
  300.     if( tf == NULL )        return;
  301.  
  302.     // Init ChunkyPort structure
  303.     cp->cp_Font       = tf;
  304.     cp->cp_TxHeight   = tf->tf_YSize;
  305.     cp->cp_TxBaseline = tf->tf_Baseline;
  306.  
  307.     // Set soft style back to normal
  308.     SetSoftStyleChk( cp, FS_NORMAL );
  309.  
  310.     // Free old TxtChunky
  311.     if(cp->cp_TxtChunky )   FreeVec( cp->cp_TxtChunky );
  312.     cp->cp_TxtChunky = NULL;
  313.  
  314.     // Install new TxtChunky
  315.     if( cp->cp_TxtChunky = AllocVec( 8*tf->tf_YSize * tf->tf_Modulo, MEMF_CLEAR|MEMF_ANY ) )
  316.     {
  317.         // Convert tf->tf_CharLoc to an array of ChunkyBytes
  318.         struct  BitMap    *bm;
  319.         struct  p2cStruct p2c;
  320.         BPTR    fh;
  321.  
  322.         if( bm = AllocBitMap( tf->tf_Modulo * 8, tf->tf_YSize, 1, BMF_CLEAR, NULL ) )
  323.         {
  324.             CopyMem( tf->tf_CharData, bm->Planes[0], tf->tf_YSize * tf->tf_Modulo );
  325.             p2c.ChunkyBuffer = cp->cp_TxtChunky;
  326.             p2c.startx       = 0;
  327.             p2c.starty       = 0;
  328.             p2c.bmap         = bm;
  329.             p2c.width        = ( tf->tf_Modulo * 8 );
  330.             p2c.height       = tf->tf_YSize;
  331.